import { globalNotLoginToken, globalToken } from './constant'

const PAGE_SIZE = 10

const formatNumber = (n) => {
  const m = n.toString()
  return m[1] ? m : `0${m}`
}

/**
 * @param date {timestamp}  时间戳
 * @param hasHouers {Boolean} 返回的类型 hhhh-mm-dd or hhhh-mm-dd hh:mm:ss;
 * @param type {String} 分隔符默认 hhhh/mm/dd
 * @return {String}  默认返回  hhhh/mm/dd hh:mm:ss
 */
const formatTime = (date, hasHouers = true, type = '/') => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()
  if (hasHouers) {
    return `${[year, month, day].map(formatNumber).join(type)} ${[
      hour,
      minute,
      second
    ]
      .map(formatNumber)
      .join(':')}`
  }
  return `${[year, month, day].map(formatNumber).join(type)}`
}

/**
 * @param fn {Function}   实际要执行的函数
 * @param delay {Number}  延迟时间，单位是毫秒（ms）
 * @return {Function}     返回一个“防反跳”了的函数
 */
const debounce = (fn, delay) => {
  let timer
  return function callBack(...args) {
    const context = this
    // const args = arguments;
    clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(context, args)
    }, delay)
  }
}

const throttle = function throttle(fn, gapTime) {
  if (gapTime == null || gapTime === undefined) {
    gapTime = 1500
  }

  let lastTime = null

  // 返回新的函数
  return function callBack() {
    const nowTime = +new Date()
    if (nowTime - lastTime > gapTime || !lastTime) {
      fn.apply(this) // 将this和参数传给原函数
      lastTime = nowTime
    }
  }
}

/**
 * 将一维数组转换成N个一组的二维数组
 * @param {Array}   arr  一维数组
 * @param {Number}  num  几个一组
 */
const mapNewList = (arr, num) => {
  const result = []
  for (let i = 0, len = arr.length; i < len; i += num) {
    result.push(arr.slice(i, i + num))
  }
  return result
}

/**
 * 将JSONParam转换成urlParam
 * @param Object  基本url
 * @param String    参数
 * @return string   返回的url
 */
// const switchUrlParam = (baseUrl, param) => `${baseUrl}?${Object.keys(param).map((key) => `${key}=${param[key]}`).join('&')}`;
const switchUrlParam = (baseUrl, param) => {
  const str = []
  Object.keys(param).forEach((key) => {
    if (param[key] !== '' && param[key] != null && param[key] !== undefined) {
      str.push(`${key}=${param[key]}`)
    }
  })
  return `${baseUrl}?${str.join('&')}`
}

/* 获取当前页url */
function getCurrentPageUrl() {
  const pages = getCurrentPages() // 获取加载的页面
  const currentPage = pages[pages.length - 1] // 获取当前页面的对象
  const url = currentPage.route // 当前页面url
  return url
}

/**
 * 获取当前页带参数的url
 */
function getCurrentPageUrlWithArgs() {
  const pages = getCurrentPages() // 获取加载的页面
  const currentPage = pages[pages.length - 1] // 获取当前页面的对象
  const url = currentPage.route // 当前页面url
  const { options } = currentPage // 如果要获取url中所带的参数可以查看options

  // 拼接url的参数
  let urlWithArgs = `${url}?`
  Object.keys(options).forEach((key) => {
    const value = options[key]
    urlWithArgs += `${key}=${value}&`
  })
  urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1)

  return urlWithArgs
}

/**
 *
 *时间戳转换为日期格式
 * @param {*} times
 * @returns
 */
function getDate(times) {
  const date = new Date(times)
  const y = 1900 + date.getYear()
  const m = `0${date.getMonth() + 1}`
  const d = `0${date.getDate()}`
  const h = `0${date.getHours()}`
  const minute = `0${date.getMinutes()}`
  const seconds = `0${date.getSeconds()}`
  return `${y}-${m.substring(m.length - 2, m.length)}-${d.substring(
    d.length - 2,
    d.length
  )} ${h.substring(h.length - 2, h.length)}:${minute.substring(
    minute.length - 2,
    minute.length
  )}:${seconds.substring(seconds.length - 2, seconds.length)}`
}

/**
 * 语音基本配置
 */
const voiceOptions = {
  duration: 30000, // 指定最大时长  默认30秒
  sampleRate: 16000, // 采样率
  numberOfChannels: 1, // 录音通道
  encodeBitRate: 96000, // 编码码率
  format: 'mp3' // 编码格式
  // frameSize: 50  // 指定帧大小
}

/**
 * 判断是否登录
 * @return {Boolean}
 */
const hasLogin = () => {
  const token = wx.getStorageSync(globalToken)
  if (token === globalNotLoginToken) return false
  return true
}

const kgUnitList = ['公斤', '斤', 'kg', 'g', 'KG', 'G', '千克', '克', '两']

const randomId = () => {
  function random() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
  }
  return `${random()}-${random()}-${random()}`
}

/*
 * 运算部件
 * */
const operationalUnit = {
  // 保留几位小数点
  toFixed: (num = 0, e) => {
    try {
      const divisor = operationalUnit.changeInit(num, e)
      num = operationalUnit.divide([divisor, Math.pow(10, e)])
    } catch (e) {
      console.error(e)
      num = 0
    }
    return num
  },
  // 获取小数点位数
  getPosition: (num = 0) => {
    // 待优化
    let e = 0
    try {
      num = parseFloat(num).toString()
      // 判断是否小于0
      let isMinus = false
      if (num.indexOf('-') !== -1) {
        isMinus = true
        num = Math.abs(num).toString()
      }

      if (num.includes('.') && num.indexOf('.') !== -1) {
        e = num.length - num.indexOf('.') - 1
      }
    } catch (e) {
      console.error(e)
    }

    return e
  },
  // 转变成整数
  changeInit: (num = 0, e) => {
    try {
      if (num == '0') return 0
      num = parseFloat(num).toString()
      // 判断是否小于0
      let isMinus = false
      if (num.indexOf('-') !== -1) {
        isMinus = true
        num = Math.abs(num).toString()
      }
      num = parseInt(Math.round(num * Math.pow(10, e)), 10) // 待优化 // '9.53' * 100

      if (isMinus) num = -num
    } catch (e) {
      console.error(e)
      num = 0
    }

    return num
  },
  // 加
  add: (arr) => {
    if (!arr.length) return 0
    let e = 0
    arr.map((item) => {
      const _e = operationalUnit.getPosition(item)
      e = _e > e ? _e : e
    })
    let total = 0
    arr.map((item, index) => {
      const num = operationalUnit.changeInit(item, e)
      if (index === 0) {
        total = num
      } else {
        total += num
      }
    })
    const m = Math.pow(10, e)
    return total / m
  },
  // 减
  cut: (arr) => {
    if (!arr.length) return 0
    let e = 0
    arr.map((item) => {
      const _e = operationalUnit.getPosition(item)
      e = _e > e ? _e : e
    })
    let total = 0
    arr.map((item, index) => {
      const num = operationalUnit.changeInit(item, e)
      if (index === 0) {
        total = num
      } else {
        total -= num
      }
    })
    const m = Math.pow(10, e)
    return total / m
  },
  // 乘
  ride: (arr) => {
    if (!arr.length) return 0
    let e = 0
    arr.map((item) => {
      const _e = operationalUnit.getPosition(item)
      e = _e > e ? _e : e
    })
    let total = 0
    arr.map((item, index) => {
      const num = operationalUnit.changeInit(item, e)
      if (index === 0) {
        total = num
      } else {
        total *= num
      }
    })
    const m = Math.pow(10, e * arr.length)
    return total / m
  },
  // 除
  divide: (arr) => {
    if (!arr.length) return 0
    let e = 0
    arr.map((item) => {
      const _e = operationalUnit.getPosition(item)
      e = _e > e ? _e : e
    })
    let total = 0
    arr.map((item, index) => {
      const num = operationalUnit.changeInit(item, e)
      if (index === 0) {
        total = num
      } else {
        total /= num
      }
    })
    return total
  }
}
// 例：
// console.error(operationalUnit.changeInit(-1))
// console.error(operationalUnit.changeInit(-1.1))
// console.error(operationalUnit.changeInit(-1.1444444))
// console.error(operationalUnit.changeInit(1.1444444))
// console.error(operationalUnit.changeInit(1.))
// console.error(operationalUnit.add([0.1, 0.1444444]))
// console.error(operationalUnit.cut([0.1, 0.1444444]))
// console.error(operationalUnit.ride([1.5, 6.35]))
// console.error(operationalUnit.ride([1.5, 0]))
// console.error(operationalUnit.divide([1.5, 6.35]))
// console.error(operationalUnit.divide([1.5, 0]))  // Infinity

// 计算价格
const countSalePrice = function (salePrice, convertRate, scale) {
  try {
    const plus = operationalUnit.add([100, scale || 0])
    const divide = operationalUnit.divide([plus, 100])
    let ride = operationalUnit.ride([divide, salePrice || 0])
    ride = operationalUnit.toFixed(ride, 2)
    const count = operationalUnit.ride([ride, convertRate || 0])
    return count.toFixed(2)
  } catch (e) {
    console.error(e)
    return 0
  }
}

module.exports = {
  formatTime,
  kgUnitList,
  voiceOptions,
  debounce,
  switchUrlParam,
  getCurrentPageUrl,
  getCurrentPageUrlWithArgs,
  getDate,
  throttle,
  hasLogin,
  mapNewList,
  randomId,
  PAGE_SIZE,
  operationalUnit,
  countSalePrice
}
